/*
 * GamestateWriter.cpp
 *
 *  Created on: Sep 8, 2009
 *      Author: mlrus
 */
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include "GamestateWriter.h"

using namespace std;

void GamestateWriter::PromptForSolution(tilemessage::SolutionSet* sol) {
    int score;
    string word;
    string cell;
    cout << "score:";
    cin >> score;
    cout << " word:";
    cin >> word;
    cout << " cell:";
    cin >> cell;
    tilemessage::SolutionSet_SolutionItem* solution = sol->add_solution();
    solution->set_word(word);
    solution->set_cell(cell);
    solution->set_score(score);
}

void GamestateWriter::generateDummySolution(tilemessage::SolutionSet* sol) {
    tilemessage::SolutionSet_SolutionItem* solution = sol->add_solution();
    string word = "word";
    string cell = "A1";
    int score = 17;
    solution->set_word(word);
    solution->set_cell(cell);
    solution->set_score(score);
    word+="1";
    score+=1;
    solution = sol->add_solution();
    solution->set_word(word);
    solution->set_cell(cell);
    solution->set_score(score);
}

void GamestateWriter::showSolution(tilemessage::SolutionSet& sol) {
    for(int i=0; i <  sol.solution_size(); i++) {
        tilemessage::SolutionSet_SolutionItem  solution = sol.solution(i);
        string cell = solution.cell();
        string word = solution.word();
        int score = solution.score();
        cout << setw(2) << cell << " :: "  << score << " :: " << word << endl;
    }
}

void GamestateWriter::PromptForGamestate(tilemessage::GameState* gs) {
    string line;
    gs->clear_gameid();
    gs->clear_playerrack();
    gs->clear_rack();
    gs->clear_row();

    cout << "Enter gameID: ";
    getline(cin,line);
    cout << "gameID: "<< line;
    gs->set_gameid(line);
    cout << endl;

    cout << "Enter rack: ";
    getline(cin, line);
    cout << "Rack:"<<line<<endl;
    gs->set_rack(line);
    cout << endl;

    cout << "Enter row data" << endl;
    while(true) {
        getline(cin,line);
        if(line.empty())break;
        gs->add_row(line);
        cout << endl;
    }
}

string GamestateWriter::construct(tilemessage::GameState& gs,vector<string>& rows, string& rack, string id) {
    gs.set_gameid(id);
    gs.set_rack(rack);
    for(vector<string>::iterator it = rows.begin(); it!=rows.end(); it++) {
        gs.add_row(*it);
    }
    return gs.SerializeAsString();
}

void GamestateWriter::generateDummyState(tilemessage::GameState* gs) {
    gs->set_gameid("sample_gameid");
    gs->set_rack("ABCDEFG");
    gs->add_row("01CDEFGHIJKLMNO");
    gs->add_row("02CDEFGHIJKLMNO");
    gs->add_row("03CDEFGHIJKLMNO");
    gs->add_row("04CDEFGHIJKLMNO");
}

int GamestateWriter::doWrite(const tilemessage::GameState& gs, const string& destination) {
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    fstream output(destination.c_str(), ios::out | ios::binary);
    if (!output) {
        cout << destination << ": File not found.  Creating a new file." << endl;
    }

    showState(gs);

    {
        // Write back to disk.
        fstream output(destination.c_str(), ios::out | ios::trunc | ios::binary);
        if (!gs.SerializeToOstream(&output)) {
            cerr << "Failed to write game state." << endl;
            return -1;
        }
    }
    return 0;
}


void GamestateWriter::showState(const tilemessage::GameState& gs) {
    std::cout << "gameid " << gs.gameid() << std::endl;
    std::cout << "  rack " << gs.rack() << std::endl;
    for(int i=0; i < gs.row().size(); i++) {
        std::cout << "  row " << gs.row(i) << std::endl;
    }
}

int GamestateWriter::readState(tilemessage::GameState* gs, const std::string& source) {
    // Verify that the version of the library that we linked against is
    // compatible with the version of the headers we compiled against.
    GOOGLE_PROTOBUF_VERIFY_VERSION;
    {
        // Read the existing game state. d

        std::fstream input(source.c_str(), std::ios::in | std::ios::binary);
        if (!gs->ParseFromIstream(&input)) {
            std::cerr << "Failed to parse game state." << std::endl;
            return -1;
        }
    }
    return 0;
}
